﻿# -*-coding:utf-8-*-
import os
import re
import shutil
import time
from time import sleep
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from retrying import retry
from Logs.log import log1
from utils import username, pwd, wait_time, files_list, pro_files, logitech_url, zipDir, update_po, e2, e1, s1, past_date, search_result_url, s2, click_upload
from PIL import ImageGrab
from selenium.webdriver.support.ui import Select
import send_email
import csv
import datetime
from selenium.webdriver import ChromeOptions


class logitech:
    def __init__(self):
        self.url = logitech_url
        option = ChromeOptions()
        option.add_experimental_option('excludeSwitches', ['enable-automation'])
        # option.set_headless()
        # option.add_argument('--disable-gpu')
        self.driver = webdriver.Chrome(chrome_options=option)
        self.master_name = ""
        self.txn_name = ""
        self.pro_file = pro_files
        self.png_path = ""

    @retry(stop_max_attempt_number=5)
    def parse_url(self):  # 发送请求
        self.driver.maximize_window()
        self.driver.set_page_load_timeout(120)
        self.driver.get(self.url)

    def login(self):  # 登录
        user_name = WebDriverWait(self.driver, wait_time).until(
            lambda driver: self.driver.find_element_by_id("unamebean"))
        password = WebDriverWait(self.driver, wait_time).until(lambda driver: self.driver.find_element_by_id("pwdbean"))
        user_name.send_keys(username)
        password.send_keys(pwd)
        WebDriverWait(self.driver, wait_time).until(EC.element_to_be_clickable((By.ID, "SubmitButton"))).click()

    def get_files(self, file_dir):
        files = os.listdir(file_dir)
        master_file = ""
        txn_file = ""
        for file in files:
            # if file.split(".")[-1] == "csv" and re.search(r"MASTER", file):
            if re.search(r"MASTER", file):
                master_file = os.path.join(file_dir, file)
                self.master_name = file.split(".")[0]
            # elif file.split(".")[-1] == "csv" and re.search(r"TXN", file):
            elif re.search(r"TXN", file):
                txn_file = os.path.join(file_dir, file)
                self.txn_name = file.split(".")[0]
        return master_file, txn_file

    def enter_upload(self):
        for i in range(3):
            try:
                click_upload(self.driver)
                break
            except:
                if i == 2:
                    return True
                self.driver.refresh()
                sleep(3)

    def upload_file(self, file_format, file_type, file_name):  # 上传文件
        # 点击选择文件
        for i in range(2):
            try:
                upload = WebDriverWait(self.driver, wait_time).until(
                    lambda driver: self.driver.find_element_by_id("LSTARfileUpload_oafileUpload"))
                # 选择本地文件
                upload.clear()
                upload.send_keys(file_format)
                # 点击 File Type下拉框
                WebDriverWait(self.driver, wait_time).until(EC.element_to_be_clickable((By.ID, "filetype"))).click()
                WebDriverWait(self.driver, wait_time).until(EC.element_to_be_clickable((By.XPATH, "//option[text()='{}']".format(file_type)))).click()
                # 点击Submit并保存Batch id
                # return self.submit(file_name)
            except:
                self.driver.refresh()
                sleep(5)
                continue

    def submit(self, file_name):
        # 点击Submit
        WebDriverWait(self.driver, wait_time).until(
            EC.element_to_be_clickable((By.XPATH, "//tr[@id='ButtonLayout__xc_']//button[@id='Submit']"))).click()
        sleep(5)
        Batch_id = None
        for i in range(3):
            try:
                conf = WebDriverWait(self.driver, wait_time).until(
                    lambda driver: self.driver.find_element_by_xpath(
                        "//table[@id='FwkErrorBeanId']//div[@class='x47']")).text
                Batch_id = re.search(r"Batch id is (\d+)", conf).group(1)
                break
            except:
                # 刷新页面
                sleep(10)
                self.driver.refresh()
        if not Batch_id:
            log1.info("{}无Batch_id".format(file_name))
            return
        return Batch_id

    def read_csv(self, master_files):
        SerialNumber = ""
        try:
            with open(master_files, "r") as f:
                files = csv.reader(f)
                num = 0
                for file in files:
                    num += 1
                    if num == 2:
                        SerialNumber = file[2]
        except:
            pass
        return SerialNumber

    def search(self, files, po):
        if re.search(r"MASTER", files):
            file_name = "master"
        elif re.search(r"TXN", files):
            file_name = "txn"
        else:
            log1.info("文件格式不符")
            return "s2"
        # 2.读取master_files(CSV文件)取出Serial Number
        SerialNumber = self.read_csv(files)
        if not SerialNumber:
            log1.info("{}_{}文件Search Results查询异常:读取CSV文件失败".format(po, file_name))
            return "s2"
        for n in range(3):
            try:
                if file_name == "master":
                    table = WebDriverWait(self.driver, wait_time).until(
                        lambda driver: self.driver.find_element_by_id("SearchLabledFieldRN"))
                    NumberInput = table.find_element_by_id("SRserialnumber")
                    DateFromInput = table.find_element_by_id("SRMFTDateFrom")
                    DateToInput = table.find_element_by_id("SRMFTDateTO")
                    SearchRecord = table.find_element_by_id("TrnSRSearchrecord")
                    Search = WebDriverWait(self.driver, wait_time).until(EC.element_to_be_clickable((By.ID, "SearchSerial")))
                else:
                    table = WebDriverWait(self.driver, wait_time).until(
                        lambda driver: self.driver.find_element_by_id("TransactionLabledRN"))
                    NumberInput = table.find_element_by_id("Trnserialnumber")
                    DateFromInput = table.find_element_by_id("TransactionDateFrom")
                    DateToInput = table.find_element_by_id("TransactionDateTO")
                    SearchRecord = table.find_element_by_id("TrnSearchrecord")
                    Search = WebDriverWait(self.driver, wait_time).until(EC.element_to_be_clickable((By.ID, "Search")))
                NumberInput.clear()
                NumberInput.send_keys(SerialNumber)
                # 3.输入查询日期
                d = datetime.date.today()
                to_date = d.strftime('%d-%m-%Y')
                from_date = past_date(d)
                DateFromInput.clear()
                DateFromInput.send_keys(from_date)
                DateToInput.clear()
                DateToInput.send_keys(to_date)
                # 4.勾选Search Related Record
                if not SearchRecord.get_attribute("checked"):
                    SearchRecord.click()
                for i in range(5):
                    # 5.点击search
                    Search.click()
                    sleep(3)
                    try:
                        # 6.以标签内容为Serial Number查询span标签定位tr标签
                        WebDriverWait(self.driver, 5).until(
                            lambda driver: self.driver.find_element_by_xpath('//td[contains(text(), "No results found.")]'))
                    except:
                        try:
                            WebDriverWait(self.driver, 5).until(
                                lambda driver: self.driver.find_element_by_xpath('//td[contains(text(), "No search conducted.")]'))
                        except:
                            log1.info("{}_{}上传查询成功".format(po, file_name))
                            # update_po(s1, batch_id, po)
                            return "s1"
                    # 7.tr标签下判断Batch Id和Source File Name
                    # 8. 6.7步ok即上传成功break
                    # 9. 循环5次5-6-7-8
                    # 10.上传失败
                    if i == 4:
                        log1.info("{}_{]文件Search Results查询无结果".format(po, file_name))
                        return "s2"
                break
            except Exception as e:
                if n == 2:
                    log1.error("{}_{}文件Search Results查询异常:{}".format(po, file_name, e))
                    return "s2"
                self.driver.refresh()
                sleep(5)

    def check(self, master_files, txn_files, batch_id, po):
        try:
            # 1.新增查询窗口
            js = 'window.open("{}");'.format(search_result_url)
            self.driver.execute_script(js)
            handles = self.driver.window_handles
            self.driver.switch_to.window(handles[1])
        except Exception as e:
            log1.error("{}文件Search Results查询异常:{}".format(po, e))
            update_po(s2, batch_id, po)
            return
        # master结果查询
        master_result = self.search(master_files, po)
        # txn结果查询
        # 点击Transactions
        for i in range(3):
            try:
                WebDriverWait(self.driver, wait_time).until(EC.element_to_be_clickable((By.ID, "LSTAR_SUBMENU_TRANSAC_TAB"))).click()
                break
            except:
                if i == 2:
                    log1.error("{}查询时点击Transactions按钮失败")
                    update_po(s2, batch_id, po)
                    return
                self.driver.refresh()
                sleep(2)
        txt_result = self.search(txn_files, po)
        if master_result == "s1" and txt_result == "s1":
            update_po(s1, batch_id, po)
        else:
            update_po(s2, batch_id, po)
        # 11.切换窗口
        self.driver.close()
        self.driver.switch_to.window(handles[0])

    def run(self, files):  # 主逻辑
        if not files:
            log1.info("zip_files目录中无上传文件")
            self.driver.close()
            return True
        hour = time.strftime("%Y%m%d%H%M%S")
        # 新建保存图片目录
        curr_path = os.path.abspath(os.path.dirname(__file__))
        save_address = os.path.join(curr_path, "zip_png")
        self.png_path = os.path.join(save_address, hour)
        try:
            os.makedirs(self.png_path)
        except:
            pass
        # 请求
        try:
            self.parse_url()
        except:
            self.driver.refresh()
            sleep(3)
        # 登录
        try:
            self.login()
        except:
            log1.error("罗技系统请求或登录失败")
            self.driver.close()
            return True
        # 点击进入上传文件页面
        if self.enter_upload():
            log1.info("点击进入罗技系统上传文件页面失败")
            self.driver.close()
            return True
        for file_dir in files:
            # 提取po
            po = re.search(r"(.*)\\(.*)", file_dir).group(2)
            master_files, txn_files = self.get_files(file_dir)
            if not (master_files and txn_files):
                log1.info("{}无符合格式的文件".format(po))
                update_po(e1, "缺失master或txn文件", po)
                # 删除文件目录
                # shutil.rmtree(file_dir)
                try:
                    shutil.move(file_dir, self.pro_file)
                except:
                    old_file = os.path.join(self.pro_file, po)
                    shutil.rmtree(old_file)
                    shutil.move(file_dir, self.pro_file)
                # 发送邮件
                # send_email.run([po])
                continue
            try:
                # 上传master文件
                file_type = "Master File"
                master_batch_id = self.upload_file(master_files, file_type, self.master_name)
                # if not master_batch_id:
                    # raise Exception("{}master上传异常".format(po))
                sleep(1)
                # 上传txn文件
                file_type = "Transaction File"
                txn_batch_id = self.upload_file(txn_files, file_type, self.txn_name)
                # if not txn_batch_id:
                    # raise Exception("{}txn上传异常".format(po))
                sleep(3)
                # batch_id = master_batch_id + "+" + txn_batch_id
                batch_id = "0"
                self.check(master_files, txn_files, batch_id, po)
            except Exception as e:
                log1.error("{}文件上传失败:{}".format(po, e))
                update_po(e2, "罗技系统网络延时或网页标签更改等, 请重试!", po)
            finally:
                # 将文件目录移到已上传的目录(process_files)
                try:
                    shutil.move(file_dir, self.pro_file)
                except:
                    old_file = os.path.join(self.pro_file, po)
                    shutil.rmtree(old_file)
                    shutil.move(file_dir, self.pro_file)
                # 发送邮件
                # send_email.run([po])
        self.driver.quit()


def run():
    files = files_list()
    lg = logitech()
    if lg.run(files):
        for file_dir in files:
            # 提取po
            po = re.search(r"(.*)\\(.*)", file_dir).group(2)
            update_po(e2, "访问罗技系统失败/无上传格式文件", po)
            try:
                shutil.move(file_dir, pro_files)
            except:
                old_file = os.path.join(pro_files, po)
                shutil.rmtree(old_file)
                shutil.move(file_dir, pro_files)



if __name__ == '__main__':
    import time
    start = time.time()
    run()
    end = time.time()
    print(end - start)
